#include "plk2gfx.h"
#include "Metagraphics.h"

RegisterCppObj<PlK2Gfx> g_register_plk2gfx;

PlK2Gfx::PlK2Gfx()
{
	_initted = false;
}

// Return the c++ type id
int PlK2Gfx::getCppTypeId()
{
	return 765281;
}

// Returns whether this can be cast to a given type
bool PlK2Gfx::isType(int id)
{
	return false;
}

// Return the c++ type as a string 
std::string PlK2Gfx::getCppTypeName()
{
	return "K2Gfx";
}

// returns a description of this thing
std::string PlK2Gfx::getDescription()
{
	return "K2 2d graphics";
}

// create another one of these
AbstractObject* PlK2Gfx::newInstance()
{
	return new PlK2Gfx;
}

// init & update
void PlK2Gfx::init()
{
	_initted = false;
}

void PlK2Gfx::update(double dt)
{
	// update thingamabobs
	//if(_initted)
		k2graphics::Metagraphics::getMetagraphics()->update(dt);
}

// push its static functions into the given lua table
void PlK2Gfx::pushStaticFuncs(lua_State* L)
{
	// push superclass static functions...
	AbstractObject::pushStaticFuncs(L);

	// just push these static funcs...
	k2graphics::Metagraphics::getLuaInterface(L);

	// push some custom ones
	static const struct luaL_Reg mylib [] = {
		{"InitGraphics", li_initGraphics},
		{"SetGUIElemAAROI", li_setAAROIRO},
		{NULL, NULL}  /* sentinel */
    };
/*
		static int li_getTextureAsImage(lua_State* L);
	static int li_setTextureFromImage(lua_State* L);
	static int li_getTextureResFromMaterial(lua_State* L);*/
	
    // dump them into said table
    luaL_register(L, NULL, mylib);
}

PlK2Gfx::~PlK2Gfx()
{
	// nothing special to do??
}

int PlK2Gfx::li_initGraphics(lua_State* L)
{
	k2graphics::Metagraphics::getMetagraphics();
	return 0;
}

//setAAROIRO(roid, x,y,width,height, rx1, ry1, rx2, ry2)
int PlK2Gfx::li_setAAROIRO(lua_State* L)
{
	int roid = (int)lua_tonumber(L,1);
	// upper left corner
	float x1 = (float)lua_tonumber(L, 2);
	float y1 = (float)lua_tonumber(L, 3);
	// w/h
	float w = (float)lua_tonumber(L, 4);
	float h = (float)lua_tonumber(L, 5);
	// uv of upper left
	float u1 = 0.0f;
	float v1 = 0.0f;
	// uv of lower right
	float u2 = 1.0f;
	float v2 = 1.0f;
	// ROI upper left
	float rx1 = (float)lua_tonumber(L, 6);
	float ry1 = (float)lua_tonumber(L, 7);
	// ROI lower right
	float rx2 = (float)lua_tonumber(L, 8);
	float ry2 = (float)lua_tonumber(L, 9);

	//LOG(logDEBUG) << "A: " << u1 << ", " << v1 << ", " << u2 << ", " << v2;

	// do clipping
	float x2 = x1 + w;
	float y2 = y1 + h;

	//LOG(logDEBUG) << "x1: " << x1 << ", rx1: " << rx1;
	//LOG(logDEBUG) << "x2: " << x2 << ", rx2: " << rx2;
	//LOG(logDEBUG) << "y1: " << y1 << ", ry1: " << ry1;
	//LOG(logDEBUG) << "y2: " << y2 << ", ry2: " << ry2;

	
	float cx1;
	float cu1;
	if(x1 >= rx1)
	{
		cx1 = x1;
		cu1 = u1;
	}
	else
	{
		cx1 = rx1;
		cu1 = ((rx1 - x1) / w) * (u2 - u1) + u1;
	}
	float cy1;
	float cv1;
	if(y1 >= ry1)
	{
		cy1 = y1;
		cv1 = v1;
	}
	else
	{
		cy1 = ry1;
		cv1 = ((ry1 - y1) / h) * (v2 - v1) + v1;
	}
	float cx2;
	float cu2;
	if(x2 <= rx2)
	{
		cx2 = x2;
		cu2 = u2;
	}
	else
	{
		cx2 = rx2;
		cu2 = ((rx2 - x1) / w) * (u2 - u1) + u1;
	}
	float cy2;
	float cv2;
	if(y2 <= ry2)
	{
		cy2 = y2;
		cv2 = v2;
	}
	else
	{
		cy2 = ry2;
		cv2 = ((ry2 - y1) / h) * (v2 - v1) + v1;
	}

	if(cx2 <= cx1 || cy2 <= cy1)
		return 0;

	k2graphics::RenderObject* theObj = k2graphics::Metagraphics::getMetagraphics()->getRenderObject(roid);

	if(theObj && theObj->rd)
	{
		k2graphics::RenderData* rd = theObj->rd;
		rd->setFloat(0, cx1);
		rd->setFloat(1, cy1);
		rd->setFloat(2, cx2);
		rd->setFloat(3, cy2);

		rd->setFloat(4, cu1);
		rd->setFloat(5, cv1);
		rd->setFloat(6, cu2);
		rd->setFloat(7, cv2);
	}
	else
		LOG(logERROR) << "No object to set RO float for!\n";



	return 0;
}